import axios from 'axios'
import {MessageBox, Message} from 'element-ui'
import store from '@/store'
import {getToken, setToken, clearStorage, getTokenTime, setTokenTime, removeTokenTime} from '@/utils/auth'
import qs from 'qs'
//导入刷新token的aoi脚本
import {refreshTokenApi} from "@/api/user";
import message from "element-ui/packages/message";
import {error} from "autoprefixer/lib/utils";
// 创建 Axios 实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials： true， // 跨域请求时发送 cookie
  timeout: 15000 // 请求超时
})

// 刷新token
function refreshTokenInfo() {
//设置请求参数
  let params = {
    token: getToken()
  }
  return refreshTokenApi(params).then(res => res)
}

//定义变量标识，标识是否正在刷新的标识
let isRefresh = false;
// 请求拦截器
service.interceptors.request.use(
  config => {
    //获取当前系统时间
    let currentTime = new Date().getTime()
    //获取token刷新时间
    let expireTime = getTokenTime()
    //判断token是否过期
    if (expireTime > 0) {
      //计算时间
      let min = (expireTime - currentTime) / 1000 / 60;
      //如果token离过期时间相差10分钟，则刷新token
      if (min <= 10) {
        //判断是否正在刷新token
        if (!isRefresh) {
          //表示刷新
          isRefresh = true;
          //调用刷新token方法
          return refreshTokenInfo().then(res => {
            //判断是否成功
            if (res.success) {
              //设置新的token和过期时间
              setToken(res.data.token);
              setTokenTime(res.data.expireTime);
              //将新的token添加到请求头中
              config.headers['token'] = getToken();
            }
            return config;
          }).catch(error => {
          }).finally(() => {
            //修改是否刷新token的状态
            isRefresh = false;
          });
        }
      }
    }
    // 在发送请求之前执行某些操作
    if (store.getters.token) {
      // 让每个请求都带有令牌
      // [token] 是自定义标头键
      // 请根据实际情况进行修改
      //读取token信息，并且添加到请求头中
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    //清空sessionStorage
    clearStorage();
    //清空token过期时间
    removeTokenTime();
    // 对请求错误执行某些操作
    console.log(error) // 用于调试
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  /**
   * 如果您想获取 http 信息，例如标头或状态
   * 请返回响应 => 响应
   */

  /**
   * 通过自定义代码确定请求状态
   * 这里只是一个例子
   * 您也可以通过HTTP状态代码来判断状态
   */
  response => {
    const res = response.data
    // 如果自定义代码不是200，则判定为错误。
    if (res.code !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        // 5秒后消失
        duration: 5 * 1000
      })
      //50008：非法令牌;50012：其他客户端已登录;50014：令牌过期;
      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // to re-login
        MessageBox.confirm('您已被注销，您可以取消以留在此页面上，或重新登录', '系统提示', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            //清空sessionStorage
            clearStorage();
            //清空token过期时间
            removeTokenTime();
            location.reload()
          })
        })
      }
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    //清空sessionStorage
    clearStorage();
    //清空token过期时间
    removeTokenTime();
    console.log('err' + error) // 用于调试
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)
//请求方法
const http = {
  /**
   * post请求
   * @param url 请求地址
   * @param params 请求参数
   * @returns 返回值
   */
  post(url, params) {
    return service.post(url, params, {
      transformRequest: [(params) => {
        return JSON.stringify(params)
      }],
      headers: {
        'Content-Type': 'application/json'
      }
    })
  },
  /**
   * put请求
   * @param url
   * @param params
   * @returns
   */
  put(url, params) {
    return service.put(url, params, {
      transformRequest: [(params) => {
        return JSON.stringify(params)
      }],
      headers: {
        'Content-Type': 'application/json'
      }
    })
  },
  /**
   * get请求
   * @param url
   * @param params
   * @returns
   */
  get(url, params) {
    return service.get(url, {
      params: params,
      paramsSerializer: (params) => {
        return qs.stringify(params)
      }
    })
  },
  /**
   * getRestApi请求
   * @param url
   * @param params
   * @returns
   */
  getRestApi(url, params) {
    let _params
    if (Object.is(params, null)) {
      _params = ''
    } else {
      _params = '/'
      for (const key in params) {
        if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== '') {
          _params += `${params[key]}/`
        }
      }
      // 去掉最后一个/
      _params = _params.substr(0, _params.length - 1)
    }
    if (_params) {
      return service.get(`${url}${_params}`)
    } else {
      return service.get(url)
    }
  },
  /**
   * delete请求
   * @param url
   * @param params
   * @returns
   */
  delete(url, params) {
    let _params
    if (Object.is(params, null)) {
      _params = ''
    } else {
      _params = '/'
      for (const key in params) {
        if (params.hasOwnProperty(key) && params[key] !== null && params[key] !== '') {
          _params += `${params[key]}/`
        }
      }
      // 去掉最后一个/
      _params = _params.substr(0, _params.length - 1)
    }
    if (_params) {
      return service.delete(`${url}${_params}`).catch(err => {
        message.error(err.msg)
        return Promise.reject(err)
      })
    } else {
      return service.delete(url).catch(err => {
        message.error(err.msg)
        return Promise.reject(err)
      })
    }
  },
  /**
   * 上传文件
   * @param url
   * @param params
   * @returns
   */
  upload(url, params) {
    return service.post(url, params, {
      headers: {
        'Content-Type': 'multipart/form-data'
      }
    })
  },
  /**
   * 登录
   * @param url
   * @param params
   * @returns
   */
  login(url, params) {
    return service.post(url, params, {
      transformRequest: [(params) => {
        return qs.stringify(params)
      }],
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    })
  }
}
export default http
